﻿//登录和鉴权模块
import java.awt.*;
import java.io.*;
import java.sql.*;
import javax.swing.*;
// 　 ∧_∧::
//　 (´･ω･`)::这里直接负责了登录和鉴权模块，主要负责与数据库的交互
///⌒　　⌒)::该有的都有了，别乱动，如果有bug请向负责该模块的开发者反馈
///へ_＿ / /::
//(＿＼＼ ﾐ)/::
//　 ｜ `-イ::
//　 /ｙ　 )::
//　/／ ／::
//／　／::
//(　く:::
//|＼ ヽ:::

public class Login {
	@SuppressWarnings("resource")
	public static void init() throws Exception {//初始化方法
		try {
			//////////////////////////////////////////////////////////////////////////////
			// 创建登录窗体，输入用户名和密码，尝试登录数据库(程序后端完全就是一个数据库)	//
			// 可以指定数据库的IP地址和端口号											//	
			// 可以勾选记住密码/自动登录											   //
			//////////////////////////////////////////////////////////////////////////
			// 创建窗体
			JFrame window = new JFrame("LogIn 登录");//创建一个窗口
			// 设置窗体大小
			window.setSize(300, 280);
			// 设置窗体居中显示
			window.setLocationRelativeTo(null);
			// 设置窗体不可修改大小
			window.setResizable(false);
			// 设置排版方式
			window.setLayout((LayoutManager) new javax.swing.BoxLayout(window.getContentPane(), javax.swing.BoxLayout.Y_AXIS));


			// 创建四个输入框，分别是用户名，密码，服务器地址，端口号
			window.add(new JLabel("用户名:"));
			JTextField userName = new JTextField();
			window.add(userName);
			window.add(new JLabel("密码:"));
			JPasswordField password = new JPasswordField();
			window.add(password);
			window.add(new JLabel("服务器地址:"));
			JTextField serverAddress = new JTextField();
			window.add(serverAddress);
			window.add(new JLabel("端口号:"));
			JTextField portNumber = new JTextField();
			window.add(portNumber);
			// 添加记住我选框
			JCheckBox rememberMe = new JCheckBox("记住我");
			window.add(rememberMe);
			// 创建登录按钮
			JButton loginBtn = new JButton("登录");
			// 添加登录按钮
			window.add(loginBtn);
			// 监听器，当点击登录时执行以下代码
			loginBtn.addActionListener(e -> {
				try {
					// 获取输入框中的内容
					String user = userName.getText();
					char[] pwd = password.getPassword();
					String serverIP = serverAddress.getText();
					int port = Integer.parseInt(portNumber.getText());
					// 连接数据库
					String url = "jdbc:mariadb://" + serverIP + ":" + port;
					// 检查密码框是否为空，如果是则使用无密码直接登录并警告用户，user用户例外，因为user用户没有权限修改任何数据
					Connection conn_ = null;
					conn_ = DriverManager.getConnection(url, user, new String(pwd));
					System.out.println("登录成功");
					// 登录成功后，将连接对象赋值给全局变量conn
					Main.conn = conn_;
					// 获取用户名
					Main.UserName = user;
					// 获取服务器地址和端口号，并保存到全局变量Server中
					Main.Server = serverIP + ":" + port;
					// 检查用户权限,先检查是否具有全局权限，如果具有则说明用户属于超管
					try {
						// 执行如下语句
						// select * from mysql.user  WHERE mysql.user.`User` = "用户名" AND mysql.`user`.`Host`="%";
						// 检查用户是否具有全局权限，如果具有则说明用户属于超管
						PreparedStatement ps = Main.conn.prepareStatement("SELECT HotelSysteam.`User`.`Level` FROM HotelSysteam.`User` WHERE HotelSysteam.`User`.`User` = '" + user + "';");// 创建查询语句
						ResultSet rs = ps.executeQuery();// 执行查询语句，并获取结果集
						// 打印结果集，方便调试
						if (rs.next()) {
							Main.Permissions = (byte)rs.getInt(1);
						}
						else
						{
							// 没有该用户，则说明用户根本不存在，但考虑到登录成功，使用弹窗提醒用户账号异常，并继续完成登录流程
							JOptionPane.showMessageDialog(window, "警告：无法获取权限数据\n账户可能存在异常\n建议联系管理员修复", "警告", JOptionPane.WARNING_MESSAGE);
							Main.Permissions = 0;
						}
						ps.close();// 关闭查询语句对象
						rs.close();// 关闭结果集对象
					}
					catch (Exception e1) {
						System.out.println("无法获取权限数据");
						Main.Permissions = 0;
						JOptionPane.showMessageDialog(window, "警告：无法获取权限数据\n账户可能存在异常或者服务器异常\n建议联系管理员修复", "警告", JOptionPane.WARNING_MESSAGE);
						e1.printStackTrace();
					}
					// 检查记住我选框是否被选中
					if (rememberMe.isSelected()) {
						// 获取用户名和密码，并保存到名为Account.data的文件中
						try {
							File file = new File("Account.data");
							if (!file.exists()) {
								file.createNewFile();
							}
							PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter(file)));// 创建文件
							pw.println(user + "\n" + new String(pwd) + "\n" + serverIP + "\n" + port);// 写入文件
							pw.close();
							System.out.println("保存成功");
						} catch (Exception e1) {
							System.out.println("保存失败，检查是否有写权限");
							e1.printStackTrace();
						}
					}
					else {
						try {
							// 删除文件
							File file = new File("Account.data");
							file.delete();
							System.out.println("删除成功");
						} catch (Exception e1) {
							// 由于如果一开始就没有文件，那么删除操作就会报错，所以这里做一个异常捕获，忽略错误
							System.out.println("删除失败，也许文件不存在？\n管它呢，反正不是错误....");
						}
					}
					// 关闭窗体
					window.setVisible(false);
				} catch (Exception e1) {
					System.out.println("登录失败");
					// 打印数据库异常信息
					e1.printStackTrace();
				}
			});
			// 读取文件，如果存在则自动填充输入框内容
			try {
				File file = new File("Account.data");
				if (file.exists()) {
					BufferedReader br = new BufferedReader(new FileReader(file));
					String user = br.readLine();// 读取用户名
					char[] pwd = br.readLine().toCharArray();// 读取密码
					String serverIP = br.readLine();// 读取服务器地址
					int port = Integer.parseInt(br.readLine());// 读取端口号
					userName.setText(user);// 填充用户名
					password.setText(new String(pwd));// 填充密码
					serverAddress.setText(serverIP);// 填充服务器地址
					portNumber.setText(String.valueOf(port));// 填充端口号
					rememberMe.setSelected(true);// 选中记住我
				}
			} catch (Exception e1) {
				System.out.println("没有找到账户记录");
			}
			// 显示窗体
			window.setVisible(true);
			// 检测窗体是否关闭，如果没关闭则一直等待
			while (window.isVisible()) {
				Thread.sleep(100);
			}
		} catch (Exception e) {
			System.out.println("登录失败");
			throw new Exception();
		}
	}
}
